package com.chen.blue.service.system.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.chen.blue.converter.system.MenuConverter;
import com.chen.blue.converter.system.MenuRoleConverter;
import com.chen.blue.converter.system.UserRoleConverter;
import com.chen.blue.domain.delete.system.MenuRoleDelete;
import com.chen.blue.domain.delete.system.UserRoleDelete;
import com.chen.blue.domain.dto.system.MenuRoleDto;
import com.chen.blue.domain.dto.system.UserRoleDto;
import com.chen.blue.domain.dto.system.update.MenuRoleDtoEdit;
import com.chen.blue.domain.dto.system.update.UserRoleDtoEdit;
import com.chen.blue.domain.model.system.MenuModel;
import com.chen.blue.domain.model.system.MenuRoleModel;
import com.chen.blue.domain.model.system.RoleModel;
import com.chen.blue.domain.model.system.UserRoleModel;
import com.chen.blue.domain.query.system.MenuQuery;
import com.chen.blue.domain.vo.system.MenuRoleVo;
import com.chen.blue.domain.vo.system.MenuVo;
import com.chen.blue.exception.e.DtoNullException;
import com.chen.blue.mapper.system.MenuRoleMapper;
import com.chen.blue.result.DataResult;
import com.chen.blue.service.candidate.CandidateInfoService;
import com.chen.blue.service.system.IMenuRoleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chen.blue.service.system.IMenuService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author CLT
 * @since 2024-05-09
 */
@Service("iMenuRoleService")
public class IMenuRoleServiceImpl extends ServiceImpl<MenuRoleMapper, MenuRoleModel> implements IMenuRoleService {

    @Resource
    private IMenuService iMenuService;

    @Override
    public boolean addRoleMenu(List<MenuRoleDto> menuRoleDtoList) throws DtoNullException {

        if (menuRoleDtoList.isEmpty()) {
            throw new DtoNullException("参数为空");
        }

        CandidateInfoService.setCreator(menuRoleDtoList);

        return super.saveBatch(MenuRoleConverter.dtoListToModelList(menuRoleDtoList));

    }

    @Override
    public boolean deleteRoleMenu(MenuRoleDelete menuRoleDelete) throws DtoNullException {

        if (Objects.isNull(menuRoleDelete)) {
            throw new DtoNullException("参数为空");
        }

        LambdaUpdateWrapper<MenuRoleModel> wrapper = new LambdaUpdateWrapper<>();
        if (Objects.nonNull(menuRoleDelete.getRoleIds()) && !menuRoleDelete.getRoleIds().isEmpty()) {
            wrapper.in(MenuRoleModel::getRoleId, menuRoleDelete.getRoleIds());
        }
        if (Objects.nonNull(menuRoleDelete.getRoleId())) {
            wrapper.or();
            wrapper.eq(MenuRoleModel::getRoleId, menuRoleDelete.getRoleId());
        }

        return Objects.nonNull(menuRoleDelete.getRoleIds()) && super.remove(wrapper);

    }

    @Override
    public boolean updateRoleMenu(List<MenuRoleDtoEdit> menuRoleDtoEditList) throws DtoNullException {

        if (menuRoleDtoEditList.isEmpty()) {
            throw new DtoNullException("参数为空");
        }

        // 将指定的用户的角色全部删除
        MenuRoleDtoEdit menuRoleDtoEdit = menuRoleDtoEditList.get(0);
        Long roleId = menuRoleDtoEdit.getRoleId();
        Map<String, Object> wrap = new HashMap<>();
        wrap.put("role_id", roleId);
        super.removeByMap(wrap);

        // 重新添加角色
        List<MenuRoleModel> menuRoleModelList = MenuRoleConverter.editDtoListToModelList(menuRoleDtoEditList);
        CandidateInfoService.setUpdater(menuRoleModelList);
        return super.saveBatch(menuRoleModelList);

    }

    @Override
    public DataResult<Map<String, Object>> queryMenuById(Long roleId) throws DtoNullException {

        if (Objects.isNull(roleId)) {
            throw new DtoNullException("参数为空");
        }

        LambdaQueryWrapper<MenuRoleModel> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MenuRoleModel::getRoleId, roleId);
        List<Long> menuIds = super.list(wrapper).stream().map(MenuRoleModel::getMenuId).collect(Collectors.toList());

        DataResult<List<MenuVo>> menuVoDataResult = iMenuService.queryMenu(new MenuQuery(), true);

        DataResult<Map<String, Object>> dataResult = new DataResult<>();
        dataResult.setData(converter(menuVoDataResult, menuIds));

        return dataResult;

    }

    @Override
    public DataResult<List<Long>> queryMenuIdsByIds(List<Long> roleIds) throws DtoNullException {

        if (Objects.isNull(roleIds) || roleIds.isEmpty()) {
            throw new DtoNullException("参数为空");
        }

        List<MenuRoleModel> list = super.list();
        List<Long> menuIds = list.stream().filter(obj -> roleIds.contains(obj.getRoleId())).map(MenuRoleModel::getMenuId).collect(Collectors.toList());

        DataResult<List<Long>> dataResult = new DataResult<>();
        dataResult.setData(menuIds);

        return dataResult;
    }


    /**
     * 转换数据，避免暴露太多数据
     *
     * @param dataResult
     * @return
     */
    protected Map<String, Object> converter(DataResult<List<MenuVo>> dataResult, List<Long> menuIds) {

        Map<String, Object> result = null;

        List<MenuVo> menuVoList = dataResult.getResult();

        if (!(Objects.nonNull(menuVoList) && !menuVoList.isEmpty())) {
            return null;
        }

        result = new HashMap<>();
        result.put("checkedKeys", menuIds);

        List<MenuRoleVo> menuRoleVoList = menuVoList.stream().map(obj -> {
            MenuRoleVo menuRoleVo = new MenuRoleVo();
            menuRoleVo.setId(obj.getId());
            menuRoleVo.setLabel(obj.getName());
            menuRoleVo.setName(obj.getName());
            if (Objects.nonNull(obj.getChildren())) {
                menuRoleVo.setChildren(setChildrenVo(obj.getChildren()));
            }
            return menuRoleVo;
        }).collect(Collectors.toList());

        result.put("menus", menuRoleVoList);

        return result;

    }

    protected List<MenuRoleVo> setChildrenVo(List<MenuVo> list) {

        return list.stream().map(obj -> {
            MenuRoleVo menuRoleVo = new MenuRoleVo();
            menuRoleVo.setId(obj.getId());
            menuRoleVo.setLabel(obj.getName());
            menuRoleVo.setName(obj.getName());
            if (Objects.nonNull(obj.getChildren())) {
                menuRoleVo.setChildren(setChildrenVo(obj.getChildren()));
            }
            return menuRoleVo;
        }).collect(Collectors.toList());

    }


}
